home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / SOURCE.ZIP / ULTIMUTE.ASM < prev    next >
Assembly Source File  |  1995-11-29  |  19KB  |  585 lines

  1. ;─────────────────────────────────────────────────────────────────────────────
  2. ;      The ULTImate MUTation Engine .93ß (c) 1993 Black Wolf Enterprises
  3. ;               pardon the title, had to think of something... }-)
  4. ;
  5. ;ULTIMUTE is a mutation engine written for security-type applications and 
  6. ;other areas where mutation of executable code is necessary.  For my personal
  7. ;use, I have implemented it in Black Wolf's File Protection Utilities 2.1s,
  8. ;using it to encrypt the code placed onto EXE's and COM's to protect them
  9. ;from simple modification and/or unauthorized use.  The encryption algorithms
  10. ;themselves are terribly simple - the main point being that they change
  11. ;each time and are difficult to trace through.  This engine is written mainly
  12. ;to keep a "hack one, hack 'em all" approach from working on protected code,
  13. ;rather than to keep the code secure by a cryptologist's point of view.
  14. ;
  15. ;Including: Better Anti-Tracing abilities, 1017 byte size, Anti-Disassembling
  16. ;           code, largely variable size for decoder.  Also includes variable
  17. ;           calling segmentation (i.e. CS<>ES<>DS, and can be called via
  18. ;           near call, far call, or interrupt, the last of which can be
  19. ;           useful as a memory-resident handler for multiple programs to
  20. ;           use).
  21. ;
  22. ;Note: Please - this program and it's source have been released as freeware,
  23. ;      but do NOT use the mutation engine in viruses!  For one thing, the
  24. ;      decryptor sequence has several repetitive sequences that can be scanned
  25. ;      for, and for another, that just isn't what it was designed for and
  26. ;      I would NOT appreciate it.  If you MUST use someone else's mutation
  27. ;      engine for such, use the TPE or MTE.  I do NOT condone such, however.
  28. ;
  29. ;Any modifications made to this program should be listed below the solid line,
  30. ;along with the name of the programmer and the date the file was changed.
  31. ;Also - they should be commented where changed.  If at all possible, report
  32. ;modifications to file to the address listed in the documentation.
  33. ;
  34. ;DISCLAIMER:  The author takes ABSOLUTELY NO RESPONSIBILITY for any damages
  35. ;resulting from the use/misuse of this program.  The user agrees to hold
  36. ;the author harmless for any consequences that may occur directly or 
  37. ;indirectly from the use of this program by utilizing this program/file
  38. ;in any manner.  Please use the engine with care.
  39. ;─────────────────────────────────────────────────────────────────────────────
  40. ;Modifications:
  41. ;       None as of yet (original release version)
  42.  
  43. .model tiny
  44. .radix 16
  45. .code
  46.  
  47.         public  _ULTMUTE, _END_ULTMUTE, Get_Rand, Init_Rand
  48.  
  49. ;Underscores are used so that these routines can be called from C and other
  50. ;upper level languages.  If you wish to use Get_Rand and Init_Rand in C, you
  51. ;need to add underscores in their names as well.  Also, the random number
  52. ;generations may not be sound for all purposes.  They do the job for this
  53. ;program, but they may/may not be mathematically correct.
  54.  
  55. ;─────────────────────────────────────────────────────────────────────────────
  56. ;ENTRY:
  57. ;       CX=Code Length          BX=New_Entry_Point
  58. ;       DS:SI=Code              AX=Calling Style
  59. ;       ES:DI=Destination               1=Near Call, 2=Far Call, 3=Int Call
  60. ;
  61. ;RETURN:
  62. ;       CX=New Size             ES:DI = Same, now contains encrypted code 
  63. ;                                       w/decryptor
  64. ;─────────────────────────────────────────────────────────────────────────────
  65. _ULTMUTE:                               
  66.         push    bp ax bx cx dx es ds si di
  67.         call    Get_Our_Offset
  68.   Offset_Mark:
  69.         inc     cx
  70.         inc     cx
  71.         mov     word ptr cs:[bp+1+Set_Size],cx
  72.         mov     word ptr cs:[Start_Pos+bp],bx
  73.         call    Init_Rand
  74.         call    Get_Base_Reg
  75.         call    Setup_Choices
  76.         call    Create_EncDec
  77.         call    Copy_Decrypt_Code
  78.         call    Encrypt_It
  79. Ending_ULTMUTE:
  80.         pop     di si ds es dx cx bx ax
  81.         add     cx,cs:[Decryptor_Length+bp]
  82.         inc     cx
  83.         inc     cx
  84.         pop     bp
  85.         cmp     ax,3       ;Select Returning method, i.e. retn, retf, iret
  86.         je      Int_Call
  87.         cmp     ax,2
  88.         je      Far_Call
  89. Near_Call:
  90.         retn
  91. Far_Call:
  92.         retf
  93. Int_Call:        
  94.         iret
  95. ;─────────────────────────────────────────────────────────────────────────────
  96. Get_Our_Offset:
  97.         mov     bp,sp
  98.         mov     bp,ss:[bp]              ;This trick finds our current offset
  99.         sub     bp,offset Offset_Mark   ;from the compiling point, as it
  100.         ret                             ;is usually not constant....
  101. ;─────────────────────────────────────────────────────────────────────────────
  102. Init_Rand:
  103.         push    ax ds
  104.         xor     ax,ax
  105.         mov     ds,ax
  106.         mov     ax,ds:[46c]             ;Get seed from timer click at
  107.         pop     ds                      ;0000:046c
  108.         mov     cs:[rand_seed+bp],ax
  109.         pop     ax
  110.         ret
  111. ;─────────────────────────────────────────────────────────────────────────────
  112. Get_Rand:
  113.         push    cx dx
  114.         mov     ax,cs:[rand_seed+bp]
  115.         mov     cx,0deadh
  116.         mul     cx                      ;This probably isn't a good algorithm,
  117.         xor     ax,0dada                ;(understatement) but it works for
  118.         ror     ax,1                    ;our purposes in this application.
  119.         mov     cs:[rand_seed+bp],ax
  120.         pop     dx cx
  121.         ret
  122. ;─────────────────────────────────────────────────────────────────────────────
  123. rand_seed       dw      0
  124. Base_Reg        db      0
  125. Base_Pointer    db      0
  126. Start_Pos       dw      0
  127. ;─────────────────────────────────────────────────────────────────────────────
  128. Get_Base_Reg:
  129.         call    Get_Rand
  130.         and     ax,11b
  131.         cmp     al,1                    ;Eliminate CX for loop purposes
  132.         je      Get_Base_Reg
  133.         mov     byte ptr cs:[bp+Base_Reg],al
  134.    Do_Pointer_Reg:
  135.         call    Get_Rand
  136.         shr     al,1
  137.         jc      Done_Base_Reg
  138.         mov     byte ptr cs:[bp+Base_Pointer],0
  139.         ret
  140.     Done_Base_Reg:
  141.         mov     byte ptr cs:[bp+Base_Pointer],1
  142.         ret
  143. ;─────────────────────────────────────────────────────────────────────────────
  144. Setup_Choices:
  145.         push    ds si        
  146.         push    cs
  147.         pop     ds
  148.         mov     si,bp
  149.  
  150.         call    Get_Rand
  151.         mov     word ptr [si+Xor_It+2],ax        ;Randomize Xor
  152.         call    Get_Rand
  153.         mov     word ptr [si+Dummy3+2],ax       ;Randomize Add/Sub
  154.         mov     word ptr [si+Dummy7+2],ax       
  155.         
  156.         call    Get_Rand                        ;Randomize Add/Sub
  157.         mov     word ptr [si+Dummy4+2],ax
  158.         mov     word ptr [si+Dummy8+2],ax
  159.  
  160.         call    Get_Rand
  161.         mov     byte ptr [si+Rand_Byte1],al     ;Randomize Random bytes
  162.         mov     byte ptr [si+Rand_Byte2],ah
  163.         call    Get_Rand 
  164.         mov     byte ptr [si+Rand_Byte3],al
  165.         mov     byte ptr [si+Rand_Byte4],ah
  166.         call    Get_Rand
  167.         mov     byte ptr [si+Rand_Byte5],al
  168.         mov     byte ptr [si+Rand_Byte6],ah
  169.         call    Get_Rand
  170.         mov     byte ptr [si+Rand_Byte7],al
  171.         mov     byte ptr [si+Rand_Byte8],ah
  172.         call    Get_Rand
  173.         mov     byte ptr [si+Rand_Byte9],al
  174.         mov     byte ptr [si+Rand_Byte10],ah
  175.  
  176.         mov     al,byte ptr [si+Base_Reg]
  177.   Set_Switcher:
  178.         and     byte ptr [si+Switcher+1],0e6       ;Delete Register
  179.         mov     ah,al
  180.         shl     ah,1
  181.         shl     ah,1
  182.         shl     ah,1
  183.         or      byte ptr [Switcher+1+si],ah
  184.     Set_Switcher_Pointer:    
  185.         push    ax
  186.         mov     al,byte ptr [si+Base_Pointer]
  187.         or      byte ptr [si+Switcher+1],al
  188.     Set_Set_Pointy:
  189.         and     byte ptr [si+Set_Pointy],0fe
  190.         or      byte ptr [si+Set_Pointy],al
  191.         and     byte ptr [si+Inc_Pointy],0fe
  192.         or      byte ptr [si+Inc_Pointy],al
  193.         and     byte ptr [si+Inc_Pointy+1],0fe
  194.         or      byte ptr [si+Inc_Pointy+1],al
  195.         pop     ax
  196.   Set_Xorit:
  197.         and     byte ptr [si+Xor_It+1],0fc
  198.         or      byte ptr [si+Xor_It+1],al
  199.   Set_Flip_It:
  200.         and     byte ptr [si+Flip_It+1],0e4
  201.         or      byte ptr [si+Flip_It+1],al
  202.         or      byte ptr [si+Flip_It+1],ah
  203.   Set_Rotate_It:
  204.         and     byte ptr [si+do_rotate+1],0fc
  205.         or      byte ptr [si+do_rotate+1],al
  206.         and     byte ptr [si+do_rot2+1],0fc
  207.         or      byte ptr [si+do_rot2+1],al
  208.   Set_IncDec:
  209.         and     byte ptr [si+inc_bx_com],0fc
  210.         or      byte ptr [si+inc_bx_com],al
  211.         and     byte ptr [si+dec_bx_com],0fc
  212.         or      byte ptr [si+dec_bx_com],al
  213.  
  214.         and     byte ptr [si+Dummy5],0fc
  215.         or      byte ptr [si+Dummy5],al
  216.         and     byte ptr [si+Dummy6],0fc
  217.         or      byte ptr [si+Dummy6],al
  218.  
  219.   Set_AddSub:
  220.         and     byte ptr [si+Dummy3+1],0fc
  221.         and     byte ptr [si+Dummy4+1],0fc
  222.         or      byte ptr [si+Dummy3+1],al
  223.         or      byte ptr [si+Dummy4+1],al
  224.         
  225.         and     byte ptr [si+Dummy7+1],0fc
  226.         and     byte ptr [si+Dummy8+1],0fc
  227.         or      byte ptr [si+Dummy7+1],al
  228.         or      byte ptr [si+Dummy8+1],al
  229.         pop     si ds
  230.         ret
  231. ;─────────────────────────────────────────────────────────────────────────────
  232. Create_EncDec:
  233.         push    es di cx
  234.         push    cs
  235.         pop     es
  236.         lea     di,[bp+Encrypt_Sequence]
  237.         call    Get_Rand
  238.         and     ax,1fh
  239.         shr     ax,1            ;Insure odd number of encryptors to prevent
  240.         shl     ax,1            ;things like "INC AX / DEC AX" to leave prog
  241.         inc     ax              ;unencrypted.
  242.  
  243.         mov     byte ptr cs:[bp+Encrypt_Length],al
  244.         xchg    cx,ax
  245. Make_Pattern:
  246.         call    Get_Rand   
  247.         and     ax,7
  248.         stosb
  249.         loop    Make_Pattern
  250.         pop     cx di es
  251.         ret
  252. ;─────────────────────────────────────────────────────────────────────────────
  253. Copy_Decrypt_Code:
  254.         push    si di bx cx ds
  255.         push    bx di                      ;save for loop
  256.  
  257.         push    cs
  258.         pop     ds
  259.  
  260.         lea     si,[bp+Set_Pointy]               
  261.         movsw
  262.         movsb
  263.         lodsb                   ;Copy initial encryptor
  264.         movsw
  265.         movsb
  266.         lodsb
  267.         movsw
  268.  
  269.         mov     cl,byte ptr cs:[bp+Encrypt_Length]
  270.         xor     ch,ch
  271.         lea     si,[Encrypt_Sequence+bp]        ;didn't have bp earlier
  272.    Dec_Set_Loop:
  273.         push    cx
  274.         lodsb        
  275.         push    si                      ;Create the Decryptor from Sequence
  276.  
  277.         mov     bl,al
  278.         xor     bh,bh
  279.         shl     bx,1
  280.         add     bx,bp
  281.         add     bx,offset Command_Table
  282.         mov     ax,cs:[bx]
  283.         
  284.         mov     cl,ah
  285.         xor     ah,ah
  286.  
  287.         lea     si,[Xor_It+bp]
  288.         add     si,ax
  289.         repnz   movsb
  290.  
  291.         pop     si
  292.         pop     cx
  293.         loop    Dec_Set_Loop
  294.  
  295.  
  296.         lea     si,[Switcher+bp]
  297.         movsw
  298.         lodsb                           ;Finish off Decryptor
  299.         movsw
  300.         lodsb
  301.         
  302.         movsw   ;Loop Setup
  303.         movsw                
  304.  
  305.         pop     si bx
  306.         mov     ax,di                   ;Set Loop
  307.         sub     ax,si                   ;Do size of loop and offset from loop
  308.         
  309.         mov     cs:[Decryptor_Length+bp],ax
  310.         
  311.         push    ax                              ;Changed for Jump
  312.         not     ax
  313.         add     ax,5
  314.         stosw
  315.         pop     ax
  316.  
  317.         add     bx,ax                   ;Set initial Pointer
  318.         mov     es:[si+1],bx
  319.                                         
  320.         mov     ax,di
  321.         pop     ds cx bx di si
  322.         push    si di bx cx
  323. Copy_Prog:
  324.         push    ax
  325.         sub     ax,di
  326.         add     ax,bx
  327.         mov     word ptr es:[di+1],ax
  328.         pop     ax        
  329.         mov     di,ax
  330.         repnz   movsb
  331.         pop     cx bx di si
  332.         ret
  333. ;─────────────────────────────────────────────────────────────────────────────
  334. Encrypt_It:
  335.         push    bx cx di si
  336.         
  337.         call    set_seqp
  338.  
  339.         mov     ax,cs:[Decryptor_Length+bp]
  340.         inc     ax
  341.         inc     ax
  342.         add     di,ax                    ;DI=start of code to be encrypted
  343.                                          ;CX=Length of code to encrypt
  344.         mov     si,di
  345.         push    es
  346.         pop     ds
  347. Big_Enc_Loop:
  348.         push    cx
  349.         call    Switcher
  350.         mov     cx,cs:[Encrypt_Length+bp]        
  351.  
  352.    Encrypt_Value:
  353.         push    ax bx cx dx si di        
  354.         mov     si,cs:[Save_SI+bp]
  355.         dec     si
  356.         mov     bl,cs:[si]              ;??
  357.         mov     cs:[Save_SI+bp],si
  358.         lea     si,cs:[Com_Table_2+bp]
  359.         xor     bh,bh
  360.         shl     bx,1
  361.         add     si,bx
  362.         mov     bx,cs:[si]
  363.         add     bx,bp
  364.         mov     word ptr cs:[Next_Command+bp],bx
  365.         pop     di si dx cx bx ax
  366.         call    cs:[Next_Command+bp]
  367.         Loop    Encrypt_Value
  368.  
  369.         pop     cx
  370.         call    Switcher
  371.         call    Inc_Pointy
  372.         call    set_seqp
  373.         loop    Big_Enc_Loop
  374.         pop     si di cx bx
  375.         ret
  376.  
  377. Save_SI         dw      0
  378. Next_Command    dw      0
  379. set_seqp:        
  380.         push    si
  381.         lea     si,cs:[Encrypt_Sequence+bp] ;SI=Encrypt_Sequence
  382.         add     si,cs:[Encrypt_Length+bp] ;SI=End of Encrypt Sequence
  383.         mov     cs:[Save_SI+bp],SI
  384.         pop     si
  385.         ret
  386. ;─────────────────────────────────────────────────────────────────────────────
  387. Command_Table:                  ;8 commands -> 3 bits.
  388.         db      [Xor_It-Xor_It],(Flip_It-Xor_It-1)
  389.         db      [Flip_It-Xor_It],(Rotate_It_1-Flip_It-1)
  390.         db      [Rotate_It_1-Xor_It],(Rotate_It_2-Rotate_It_1-1)
  391.         db      [Rotate_It_2-Xor_It],(Dummy1-Rotate_It_2-1)
  392.         db      [Dummy1-Xor_It],(Dummy2-Dummy1-1)
  393.         db      [Dummy2-Xor_It],(Dummy3-Dummy2-1)
  394.         db      [Dummy3-Xor_It],(Dummy4-Dummy3-1)
  395.         db      [Dummy4-Xor_It],(Dummy5-Dummy4-1)
  396. Com_Table_2:
  397.         dw      [offset Xor_It]
  398.         dw      [offset Flip_It]
  399.         dw      [offset Rotate_It_2]
  400.         dw      [offset Rotate_It_1]
  401.         dw      [offset Dummy5]
  402.         dw      [offset Dummy6]
  403.         dw      [offset Dummy7]
  404.         dw      [offset Dummy8]
  405. ;─────────────────────────────────────────────────────────────────────────────
  406. Set_Pointy:
  407.         mov     di,1234 ;Pointer to Code
  408.         ret
  409. Set_Size:        
  410.         mov     cx,1234 ;Size
  411.         ret
  412. Switcher:
  413.         xchg    bx,[di]
  414.         ret
  415. Inc_Pointy:
  416.         inc     di
  417.         inc     di
  418.         ret
  419.  
  420. Loop_Mut:       
  421.         dec     cx
  422.         jz      End_Loop_Mut
  423.     loop_set:
  424.         jmp     _ULTMUTE
  425.     End_Loop_Mut:
  426.         ret
  427. Xor_It: 
  428.         xor     bx,1234
  429.         ret
  430. Flip_It:
  431.         xchg    bh,bl
  432.         ret
  433.  
  434. Rotate_It_1:
  435.         jmp     before_rot
  436. do_rotate:
  437.         ror     bx,1
  438.         jmp     after_rot
  439. before_rot:  
  440.         push    ax
  441.         call    Ports1
  442.         pop     ax
  443.         jmp     do_rotate
  444. Ports1:
  445.         in      al,21
  446.         or      al,02
  447.         out     21,al
  448.         ret
  449.  
  450. Ports2:        
  451.         in      al,21
  452.         xor     al,02
  453.         out     21,al
  454.         ret
  455. after_rot:        
  456.         push    ax
  457.         call    ports2
  458.         pop     ax
  459.         ret
  460.  
  461. Rotate_It_2:
  462.         cli
  463.         jmp     confuzzled1
  464. do_rot2:        
  465.         rol     bx,1
  466.         call    Switch_Int_1_3
  467.         jmp     donerot2
  468.         
  469. confuzzled1:
  470.         call    Switch_Int_1_3
  471.         jmp     do_rot2
  472.  
  473. Switch_Int_1_3:        
  474.         push    ax ds
  475.         xor     ax,ax
  476.         mov     ds,ax
  477.         jmp     short exch1
  478.         db      0eah
  479. exch1:
  480.         xchg    ax,word ptr ds:[4]
  481.         jmp     short exch2
  482.         db      9ah
  483. exch2:
  484.         xchg    ax,word ptr ds:[0c]
  485.         xchg    ax,word ptr ds:[4]
  486.         pop     ds ax
  487.         ret
  488. donerot2:
  489.         ret
  490.  
  491. Dummy1:
  492.         jmp     short inc_bx_com              ;Kill Disassemblers
  493.         db      0ea
  494.    Rand_Byte1:        
  495.         db      0ea
  496.    inc_bx_com:
  497.         inc     bx
  498.         ret
  499. Dummy2:
  500.         jmp     short Kill_1
  501.   Rand_Byte2:        
  502.         db      0ea
  503.   Cont_Kill1:
  504.         cli
  505.         xchg    ax,ds:[84]
  506.         xchg    ax,ds:[84]
  507.         sti
  508.         pop     ds ax
  509.    dec_bx_com:        
  510.         dec     bx
  511.         jmp     short quit_Kill1
  512.      Kill_1:
  513.         push    ax ds
  514.         xor     ax,ax
  515.         mov     ds,ax                   ;Anti-Debugger (Kills Int 21)
  516.         jmp     short Cont_Kill1
  517.      Rand_Byte3:
  518.         db      0e8
  519.    quit_Kill1:
  520.         ret
  521. Dummy3:
  522.         add     bx,1234
  523.         push    bx
  524.         call    throw_debugger
  525.    Rand_Byte4:
  526.         db      0e8                             ;Prefetch Trick
  527.    into_throw:
  528.         sub     bx,offset Rand_Byte4
  529.         add     byte ptr [bx+trick_em+1],0ba
  530.    trick_em:        
  531.         jmp     short done_trick
  532.    Rand_Byte5:
  533.         db      0ea
  534.    throw_debugger:
  535.         pop     bx
  536.         jmp     short into_throw
  537.    Rand_Byte6:
  538.         db      0ea
  539.    done_trick:
  540.         sub     byte ptr [bx+trick_em+1],0ba
  541.         pop     bx
  542.         ret
  543. Dummy4:
  544.         sub     bx,1234
  545.         jmp     short Get_IRQ
  546. Rand_Byte7   db      0e8
  547. Kill_IRQ:        
  548.         out   21,al
  549.         xor   al,2
  550.         jmp   short Restore_IRQ
  551. Rand_Byte8   db      0e8        
  552. Rand_Byte9   db      0e8                ;This will kill the keyboard
  553.    Get_IRQ:                             ;IRQ
  554.         push    ax
  555.         in    al,21
  556.         xor   al,2
  557.         jmp    short  Kill_IRQ
  558. Rand_Byte10  db      0e8
  559. Restore_IRQ:        
  560.         out   21,al
  561.         pop     ax
  562.         ret
  563.  
  564. ;The following are used for the encryption algorithm to reverse commands that
  565. ;include anti-tracing.
  566. Dummy5: 
  567.         dec     bx
  568.         ret
  569. Dummy6:
  570.         inc     bx
  571.         ret
  572. Dummy7:
  573.         sub     bx,1234
  574.         ret
  575. Dummy8:
  576.         add     bx,1234
  577.         ret
  578. ;─────────────────────────────────────────────────────────────────────────────
  579. Decryptor_Length        dw      0
  580. Encrypt_Length          dw      0
  581. Encrypt_Sequence        db      30 dup(0)
  582. ;─────────────────────────────────────────────────────────────────────────────
  583. _END_ULTMUTE:
  584. end _ULTMUTE
  585.